package xyz.yuzegod.megawalls.classes.normal.spider;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import xyz.yuzegod.megawalls.MegaWalls;
import xyz.yuzegod.megawalls.classes.Classes;
import xyz.yuzegod.megawalls.classes.Skill;
import xyz.yuzegod.megawalls.game.GamePlayer;
import xyz.yuzegod.megawalls.stats.KitStatsContainer;
import xyz.yuzegod.megawalls.util.ParticleEffect;
import xyz.yuzegod.megawalls.util.PlayerUtils;

import java.util.ArrayList;
import java.util.List;

public class MainSkill extends Skill
{
    public MainSkill(final Classes classes) {
        super("跳跃", classes);
    }
    
    @Override
    public int maxedLevel() {
        return 5;
    }
    
    @Override
    public double getAttribute(final int level) {
        switch (level) {
            case 1: {
                return 3.0;
            }
            case 2: {
                return 3.5;
            }
            case 3: {
                return 4.0;
            }
            case 4: {
                return 4.5;
            }
            case 5: {
                return 5.0;
            }
            default: {
                return 3.0;
            }
        }
    }
    
    public int getHits(final int level) {
        switch (level) {
            case 1: {
                return 1;
            }
            case 2: {
                return 2;
            }
            case 3: {
                return 3;
            }
            case 4: {
                return 3;
            }
            case 5: {
                return 4;
            }
            default: {
                return 1;
            }
        }
    }
    
    @Override
    public List<String> getInfo(final int level) {
        final List<String> lore = new ArrayList<String>();
        if (level == 1) {
            lore.add(" §8▪ §7向前跳跃至空中,获得5秒的生命");
            lore.add("   §7恢复I效果。落地时,周围敌人受");
            lore.add("   §7到§a" + this.getAttribute(level) + "§7点伤害和持续4秒的缓慢I效果,");
            lore.add("   §7你则获得§a" + this.getHits(level) + "§7次毒液之击的机会。");
            return lore;
        }
        lore.add(" §8▪ §7向前跳跃至空中,获得5秒的生命");
        lore.add("   §7恢复I效果。落地时,周围敌人受");
        lore.add("   §7到§8" + this.getAttribute(level - 1) + " ➜ §a" + this.getAttribute(level) + "§7点伤害和持续4秒的缓慢I效果,");
        lore.add("   §7你则获得§8" + this.getHits(level - 1) + ((this.getHits(level - 1) == this.getHits(level)) ? "" : (" ➜ §a" + this.getHits(level))) + "§7次毒液之击的机会。");
        return lore;
    }
    
    @Override
    public void upgrade(final GamePlayer gamePlayer) {
        final KitStatsContainer kitStats = gamePlayer.getPlayerStats().getKitStats(this.getClasses());
        kitStats.addSkillLevel();
    }
    
    @Override
    public int getPlayerLevel(final GamePlayer gamePlayer) {
        return gamePlayer.getPlayerStats().getKitStats(this.getClasses()).getSkillLevel();
    }
    
    @Override
    public boolean use(final GamePlayer gamePlayer, final KitStatsContainer kitStats) {
        final Player player = gamePlayer.getPlayer();
        final Vector vector = player.getLocation().getDirection().multiply(6.5);
        if (vector.getY() > 2.0) {
            vector.setY(2.0);
        }
        player.setVelocity(vector);
        player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 100, 0));
        player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, 40, 0));
        new BukkitRunnable() {
            private List<FallingBlock> fallingBlocks = new ArrayList<FallingBlock>();
            
            public void run() {
                if (!player.isOnline()) {
                    this.cancel();
                    return;
                }
                if (!player.isOnGround()) {
                    return;
                }
                Spider.skill2.put(gamePlayer, MainSkill.this.getHits(kitStats.getSkillLevel()));
                for (final Player player1 : MainSkill.this.getNearbyPlayers(player, MainSkill.this.getAttribute(kitStats.getSkillLevel()))) {
                    player1.damage(MainSkill.this.getAttribute(kitStats.getSkillLevel()));
                    player1.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 80, 0));
                }
                ParticleEffect.EXPLOSION_HUGE.display(0.0f, 0.0f, 0.0f, 1.0f, 1, player.getLocation().add(0.0, 1.0, 0.0), 10.0);
                player.getWorld().playSound(player.getLocation(), Sound.EXPLODE, 1.0f, 0.5f);
                final Location location = player.getLocation().add(0.0, 2.0, 0.0);
                ParticleEffect.LAVA.display(0.0f, 0.0f, 0.0f, 1.0f, 20, location, 10.0);
                location.getWorld().playSound(location, Sound.SPIDER_DEATH, 1.0f, 0.0f);
                final FallingBlock fb = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb2 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb3 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb4 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb5 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb6 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb7 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                final FallingBlock fb8 = location.getWorld().spawnFallingBlock(location, Material.WEB, (byte)0);
                this.fallingBlocks.add(fb);
                this.fallingBlocks.add(fb2);
                this.fallingBlocks.add(fb3);
                this.fallingBlocks.add(fb4);
                this.fallingBlocks.add(fb5);
                this.fallingBlocks.add(fb6);
                this.fallingBlocks.add(fb7);
                this.fallingBlocks.add(fb8);
                final double vector = 0.4;
                final double vector2 = 0.3;
                fb.setVelocity(new Vector(vector, 0.0, 0.0));
                fb2.setVelocity(new Vector(0.0, 0.0, vector));
                fb3.setVelocity(new Vector(-vector, 0.0, 0.0));
                fb4.setVelocity(new Vector(0.0, 0.0, -vector));
                fb5.setVelocity(new Vector(vector2, 0.0, vector2));
                fb6.setVelocity(new Vector(-vector2, 0.0, vector2));
                fb7.setVelocity(new Vector(vector2, 0.0, -vector2));
                fb8.setVelocity(new Vector(-vector2, 0.0, -vector2));
                final FallingBlock[] array;
                final FallingBlock[] fallingBlocks = array = new FallingBlock[] { fb, fb2, fb3, fb4, fb5, fb6, fb7, fb8 };
                for (final FallingBlock fallingBlock : array) {
                    fallingBlock.setMetadata(MegaWalls.getMetadataValue(), (MetadataValue)MegaWalls.getFixedMetadataValue());
                    fallingBlock.setDropItem(false);
                }
                for (final Block block1 : MainSkill.getSphere(player.getLocation().clone().add(0.0, -1.0, 0.0), 5)) {
                    if (!MegaWalls.getInstance().getGame().isUnbreakable(block1.getLocation()) && ((block1.getType() != Material.FURNACE && block1.getType() != Material.BURNING_FURNACE && block1.getType() != Material.TRAPPED_CHEST && block1.getType() != Material.BARRIER) || gamePlayer.isProtectedBlock(block1))) {
                        if (block1.getType() == Material.BEDROCK) {
                            continue;
                        }
                        block1.breakNaturally();
                    }
                }
                for (final Block block1 : MainSkill.getSphere(player.getLocation().clone().add(0.0, -2.0, 0.0), 4)) {
                    if (!MegaWalls.getInstance().getGame().isUnbreakable(block1.getLocation()) && ((block1.getType() != Material.FURNACE && block1.getType() != Material.BURNING_FURNACE && block1.getType() != Material.TRAPPED_CHEST && block1.getType() != Material.BARRIER) || gamePlayer.isProtectedBlock(block1))) {
                        if (block1.getType() == Material.BEDROCK) {
                            continue;
                        }
                        block1.breakNaturally();
                    }
                }
                for (final Block block1 : MainSkill.getSphere(player.getLocation().clone().add(0.0, -3.0, 0.0), 3)) {
                    if (!MegaWalls.getInstance().getGame().isUnbreakable(block1.getLocation()) && ((block1.getType() != Material.FURNACE && block1.getType() != Material.BURNING_FURNACE && block1.getType() != Material.TRAPPED_CHEST && block1.getType() != Material.BARRIER) || gamePlayer.isProtectedBlock(block1))) {
                        if (block1.getType() == Material.BEDROCK) {
                            continue;
                        }
                        block1.breakNaturally();
                    }
                }
                Bukkit.getScheduler().runTaskLater((Plugin)MegaWalls.getInstance(), (Runnable)new Runnable() {
                    @Override
                    public void run() {
                        Spider.skill2.put(gamePlayer, 0);
                    }
                }, 400L);
                this.cancel();
            }
        }.runTaskTimer((Plugin)MegaWalls.getInstance(), 10L, 1L);
        return true;
    }
    
    public static List<Block> getSphere(final Location location, final int radius) {
        final List<Block> blocks = new ArrayList<Block>();
        final int X = location.getBlockX();
        final int Y = location.getBlockY();
        final int Z = location.getBlockZ();
        final int radiusSquared = radius * radius;
        for (int x = X - radius; x <= X + radius; ++x) {
            for (int z = Z - radius; z <= Z + radius; ++z) {
                if ((X - x) * (X - x) + (Z - z) * (Z - z) <= radiusSquared) {
                    blocks.add(location.getWorld().getBlockAt(x, Y, z));
                }
            }
        }
        return blocks;
    }
    
    private List<Player> getNearbyPlayers(final Player player, final double radius) {
        final List<Player> players = new ArrayList<Player>();
        for (final Player other : PlayerUtils.getNearbyPlayers((Entity)player, radius)) {
            final GamePlayer gameOther = GamePlayer.get(other.getUniqueId());
            if (!gameOther.isSpectator()) {
                if (GamePlayer.get(player.getUniqueId()).getGameTeam().isInTeam(gameOther)) {
                    continue;
                }
                players.add(other);
            }
        }
        return players;
    }
}
